package pl.nazaweb.samplesandtutorials.abstracts.contentproviders;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;

public abstract class AbstractContentProvider extends ContentProvider {

	public abstract AbstractTable getTable();

	public abstract String getDatabaseName();

	public abstract int getDatabaseVersion();

	public static final int COLECTION_URI = 1;
	public static final int ITEM_URI = 2;
	private UriMatcher uriMatcher;
	private DatabaseHelper databaseHelper;

	public UriMatcher getUriMatcher() {
		if (uriMatcher == null) {
			uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
			uriMatcher.addURI(getTable().getAuthority(), getTable()
					.getTableName(), COLECTION_URI);
			uriMatcher.addURI(getTable().getAuthority(), getTable()
					.getTableName().concat("/#"), ITEM_URI);
		}
		return uriMatcher;
	}

	@Override
	public int delete(Uri uri, String whereClause, String[] whereArgs) {
		SQLiteDatabase dataBase = databaseHelper.getReadableDatabase();
		int deletedRows = 0;
		int uriMatch = getUriMatcher().match(uri);
		whereClause = getDeleteUpdateWhereCalusule(uri, whereClause, uriMatch);
		if (uriMatch != COLECTION_URI && uriMatch != ITEM_URI) {
			throw new IllegalArgumentException("Not know uri : " + uri);
		}
		dataBase.delete(getTable().getTableName(), whereClause, whereArgs);
		getContext().getContentResolver().notifyChange(uri, null);
		return deletedRows;
	}

	private String getDeleteUpdateWhereCalusule(Uri uri, String whereClause,
			int uriMatch) {
		if (uriMatch == ITEM_URI) {
			String rowTodeleteId = uri.getPathSegments().get(1);
			whereClause = AbstractTable._ID
					.concat(" = ")
					.concat(rowTodeleteId)
					.concat(TextUtils.isEmpty(whereClause) ? " AND where ( "
							.concat(whereClause).concat(" )") : "");
		}
		return whereClause;
	}

	@Override
	public String getType(Uri uri) {
		switch (getUriMatcher().match(uri)) {
		case COLECTION_URI: {
			return getTable().getContentType();
		}
		case ITEM_URI: {
			return getTable().getContentSingleItemType();
		}
		default:
			throw new IllegalArgumentException("Not know uri : " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		if (getUriMatcher().match(uri) != COLECTION_URI) {
			throw new IllegalArgumentException(
					"Wrong uri for insert statement : " + uri);
		}

		if (values != null) {
			values = new ContentValues(values);
		} else {
			values = new ContentValues();
		}

		SQLiteDatabase dataBase = databaseHelper.getReadableDatabase();
		Long rowId = dataBase.insert(getTable().getTableName(), null, values);

		if (rowId > 0) {
			Uri insertedUri = ContentUris.withAppendedId(getTable()
					.getContentUri(), rowId);
			getContext().getContentResolver().notifyChange(insertedUri, null);
			return insertedUri;
		}
		return null;
	}

	@Override
	public boolean onCreate() {
		List<AbstractTable> tableList = new ArrayList<AbstractTable>();
		tableList.add(getTable());
		databaseHelper = new DatabaseHelper(getContext(), getDatabaseName(),
				tableList, getDatabaseVersion());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder query = new SQLiteQueryBuilder();
		query = getSimpleQuery();
		int uriMatch = getUriMatcher().match(uri);
		if (uriMatch == ITEM_URI) {
			query.appendWhere(BaseColumns._ID
					.concat(" = ").concat(uri.getPathSegments().get(1)));
		}

		if (uriMatch != COLECTION_URI && uriMatch != ITEM_URI) {
			throw new IllegalArgumentException("nieznany uri");
		}

		if (TextUtils.isEmpty(sortOrder)) {
			sortOrder = getTable().getDefaultSortOrder();
		}

		SQLiteDatabase dataBase = databaseHelper.getReadableDatabase();
		Cursor queryCursor = query.query(dataBase, projection, selection,
				selectionArgs, null, null, sortOrder);

		queryCursor.setNotificationUri(getContext().getContentResolver(), uri);

		return queryCursor;
	}

	private SQLiteQueryBuilder getSimpleQuery() {
		SQLiteQueryBuilder query = new SQLiteQueryBuilder();
		query.setTables(getTable().getTableName());
		query.setProjectionMap(getTable().getProjectionColumns());
		return query;
	}

	@Override
	public int update(Uri uri, ContentValues values, String whereClause,
			String[] whereArgs) {
		SQLiteDatabase dataBase = databaseHelper.getReadableDatabase();
		int updatedRows = 0;
		int uriMatch = getUriMatcher().match(uri);
		whereClause = getDeleteUpdateWhereCalusule(uri, whereClause, uriMatch);
		if(uriMatch!=ITEM_URI && uriMatch!=COLECTION_URI){
			throw new IllegalArgumentException("Not know uri " + uri);
		}
		dataBase.update(getTable().getTableName(), values, whereClause, whereArgs);
		getContext().getContentResolver().notifyChange(uri, null);
		return updatedRows;
	}

}
